package com.yzcrm.erp.psi.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.yzcrm.common.config.paragetter.BasePageRequest;
import com.yzcrm.common.constant.BaseConstant;
import com.yzcrm.erp.admin.entity.AdminField;
import com.yzcrm.erp.admin.entity.AdminScene;
import com.yzcrm.erp.admin.service.AdminFieldService;
import com.yzcrm.erp.admin.service.AdminRoleService;
import com.yzcrm.erp.admin.service.AdminSceneService;
import com.yzcrm.erp.admin.service.AdminUserService;
import com.yzcrm.erp.crm.common.CrmEnum;
import com.yzcrm.erp.crm.service.CrmRecordService;
import com.yzcrm.erp.psi.entity.PsiStockpile;
import com.yzcrm.erp.psi.entity.PsiStorehouse;
import com.yzcrm.utils.AuthUtil;
import com.yzcrm.utils.BaseUtil;
import com.yzcrm.utils.ParamsUtil;
import com.yzcrm.utils.R;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jiang.xue
 */
public class PsiStoreHouseService {

    @Inject
    private CrmRecordService crmRecordService;

    @Inject
    private AdminFieldService adminFieldService;

    @Inject
    private AdminSceneService adminSceneService;

    /**
     * 追加仓库
     * @param jsonObject
     * @return
     */
    @Before(Tx.class)
    public R addOrUpdate(JSONObject jsonObject) {

        PsiStorehouse psiStorehouse = jsonObject.getObject("entity", PsiStorehouse.class);
        if(ObjectUtil.isNull(psiStorehouse)) {
            R.error("参数不正确");
        }

        String batchId = StrUtil.isNotEmpty(psiStorehouse.getBatchId()) ? psiStorehouse.getBatchId() : IdUtil.simpleUUID();
        if(psiStorehouse.getStorehouseId() != null){
            crmRecordService.updateRecord(jsonObject.getJSONArray("field"), batchId);
        }
        adminFieldService.save(jsonObject.getJSONArray("field"), batchId);
        boolean flag = false;
        if(psiStorehouse.getStorehouseId() != null){

            psiStorehouse.setCheckStatus(1); // 仓库暂时不用审核
            PsiStorehouse oldPsiStorehouse = PsiStorehouse.dao.findById(psiStorehouse.getStorehouseId());
            crmRecordService.updateRecord(oldPsiStorehouse, psiStorehouse, CrmEnum.PSI_STOREHOUSE);
            psiStorehouse.setUpdateTime(DateUtil.date());
            psiStorehouse.setUpdateUserId(BaseUtil.getUser().getUserId());
            flag = psiStorehouse.update();
        }else{
            psiStorehouse.setCreateTime(DateUtil.date());
            psiStorehouse.setUpdateTime(DateUtil.date());
            psiStorehouse.setCreateUserId(BaseUtil.getUser().getUserId());
            psiStorehouse.setBatchId(batchId);
            psiStorehouse.setCheckStatus(1);// 仓库暂时不用审核
            psiStorehouse.setStatus(1);
//            psiStorehouse.setOwnerUserId(BaseUtil.getUser().getUserId());

            flag = psiStorehouse.save();

            // 增加在库
            List<Record> listProduct = Db.find(Db.getSql("crm.product.getProductAndSpec"));
            for (int i = 0; i < listProduct.size(); i++) {

                Record record = listProduct.get(i);
                // 检索在库是否存在
                PsiStockpile stockpile = PsiStockpile.dao.findFirst(Db.getSql("psi.stockpile.queryStockpileByStorehouseProductSpec"),
                        psiStorehouse.getStorehouseId(), record.getInt("product_id"), record.getInt("product_spec_id"));
                if (ObjectUtil.isNull(stockpile)) {

                    stockpile = new PsiStockpile();
                    stockpile.setProductSpecId(record.getInt("product_spec_id"));
                    stockpile.setProductId(record.getInt("product_id"));
                    stockpile.setStorehouseId(psiStorehouse.getStorehouseId());
                    stockpile.setQuantity(0);
                    stockpile.setMinnumWarn(0);
                    stockpile.setMaxnumWarn(0);
                    stockpile.setCreateTime(DateUtil.date());
                    stockpile.setCreateUserId(BaseUtil.getUser().getUserId());
                    stockpile.setUpdateTime(DateUtil.date());
                    stockpile.setStatus(1);
                    stockpile.save();
                }

            }

            crmRecordService.addRecord(psiStorehouse.getStorehouseId(), CrmEnum.PSI_STOREHOUSE);
        }

        return flag ? R.ok().put("data", Kv.by("storehouse_id", psiStorehouse.getStorehouseId()).set("name", psiStorehouse.getName())) : R.error();
    }

    /**
     * 获取场景 并 获取进销存列表
     * @param basePageRequest
     * @return
     */
    public R filterConditionAndGetPageList(BasePageRequest basePageRequest){

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Integer sceneId = jsonObject.getInteger("sceneId");
        JSONObject data = new JSONObject();
        if(sceneId != null && sceneId != 0){
            data = JSON.parseObject(AdminScene.dao.findById(sceneId).getData());
        }
        if(sceneId == null && jsonObject.getInteger("type") == 1){
            data = new JSONObject().fluentPut("is_transform", new JSONObject().fluentPut("name", "is_transform").fluentPut("condition", "is").fluentPut("value", "0"));
        }
        if(jsonObject.getJSONObject("data") != null){
            if(data != null){
                data.putAll(jsonObject.getJSONObject("data"));
            }
        }
        jsonObject.put("data",data);
        basePageRequest.setJsonObject(jsonObject);
        return getStorehousePageList(basePageRequest);
    }

    /**
     * 获取进销存列表
     * @param basePageRequest
     * @return
     */
    public R getStorehousePageList(BasePageRequest basePageRequest) {

        JSONObject jsonObject = basePageRequest.getJsonObject();
        Kv kv = new Kv();
        List<JSONObject> queryList = new ArrayList<>();
        Integer type = jsonObject.getInteger("type");
        boolean isValid = jsonObject.getBoolean("isValid") != null ? jsonObject.getBoolean("isValid") : false;

        //自定义字段列表
        Map<String, AdminField> fieldMap = adminSceneService.getAdminFieldMap(type);

        // 取得场景名称 同label
        String realm = CrmEnum.parse(type).getName();
        if(ObjectUtil.isNull(realm)) {
            return R.error("type不符合要求");
        }

        // 附加检索条件
        JSONObject data = basePageRequest.getJsonObject().getJSONObject("data");
        if (!adminSceneService.appendSqlCondition(kv, fieldMap, queryList, data, type)){
            return R.error("参数包含非法字段");
        }
        String search = basePageRequest.getJsonObject().getString("search");
        if(StrUtil.isNotEmpty(search)){
            if (!adminSceneService.appendSqlSearch(type, queryList, search)){
                return R.error("参数包含非法字段");
            }
            if(!kv.containsKey("fixed")){
                kv.set("fixed",true);
            }
        }

        // 获取排序字段
        String camelField = basePageRequest.getJsonObject().getString("sortField");
        String sortField = StrUtil.toUnderlineCase(camelField);
        String orderNum = basePageRequest.getJsonObject().getString("order");
        if(StrUtil.isEmpty(sortField) || StrUtil.isEmpty(orderNum)){
            kv.set("orderByKey", "update_time").set("orderByType", "desc").set("fieldType", 1);
        }else{
            if(! ParamsUtil.isValid(sortField)){
                return R.error("参数包含非法字段");
            }
            orderNum = "2".equals(orderNum) ? "asc" : "desc";
            kv.set("orderByKey", sortField).set("orderByType", orderNum).set("fieldType", fieldMap.get(sortField) != null ? fieldMap.get(sortField).getFieldType() : 0);
        }

        // 开始生成条件SQL
        StringBuilder conditions = new StringBuilder();

        //获取已审核数据
        if(isValid) {
            conditions.append(" and check_status = 1");
        }

        conditions.append(" and status != 2 ");

        // 检索权限
        Long userId = BaseUtil.getUserId();
        List<Integer> roles = BaseUtil.getUser().getRoles();
        if(! BaseConstant.SUPER_ADMIN_USER_ID.equals(userId) && !roles.contains(BaseConstant.SUPER_ADMIN_ROLE_ID)){

            String menuRealm = "storehouse";

            List<Long> longs = Aop.get(AdminUserService.class).queryUserByAuth(userId, menuRealm);
            if(longs != null && longs.size() > 0){
                conditions.append(" and (a.owner_user_id in (").append(StrUtil.join(",", longs)).append(")");
                conditions.append(")");
            }
        }
        JSONObject sqlObject = new JSONObject();
        sqlObject.put("sql", conditions.toString());
        sqlObject.put("type", 1);
        if(!kv.containsKey("fixed")){
            kv.set("fixed",true);
        }
        queryList.add(sqlObject);

        // 设置分页
        if(StrUtil.isEmpty(basePageRequest.getJsonObject().getString("excel"))){
            kv.set("page", (basePageRequest.getPage() - 1) * basePageRequest.getLimit()).set("limit", basePageRequest.getLimit());
        }

        String selectSql = "select * ";
        List<String> batchList = adminSceneService.queryBatchId(queryList);
        if(batchList.size()==0&&kv.containsKey("field")){
            batchList.add("");
        }
        kv.set("select", selectSql).set("queryList", queryList).set("realm", realm).set("fieldMap", fieldMap).set("label", type);
        kv.set("batchList",batchList);
        SqlPara sqlPara = null;
        if(kv.getInt("fieldType") == 0){
            sqlPara = Db.getSqlPara("psi.storehouse.queryStoreHousePageList2", kv);
        }else{
            sqlPara = Db.getSqlPara("psi.storehouse.queryStoreHousePageList1", kv);
        }

        // 检索数据
        List<Record> recordPage = Db.find(sqlPara);

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", recordPage);
        SqlPara countSql = Db.getSqlPara("psi.storehouse.queryPsiStoreHousePageListCount", kv);
        Integer count = Db.queryInt(countSql.getSql(), countSql.getPara());
        resultJsonObject.put("totalRow", count);
        return R.ok().put("data", resultJsonObject);

    }

    /**
     * @author wyq
     * 根据仓库id查询
     */
    public Record queryById(Integer storehouseId){
        Record record = Db.findFirst(Db.getSql("psi.storehouse.queryById"), storehouseId);
        List<Record> recordList = Db.find("select name,value from `yzcrm_admin_fieldv` where batch_id = ?", record.getStr("batch_id"));
        recordList.forEach(field -> record.set(field.getStr("name"), field.getStr("value")));
        return record;
    }

    /**
     * @author lg
     * 查询编辑字段
     */
    public List<Record> queryField(Integer storehouseId){
        Record storehouse = queryById(storehouseId);
        List<Record> fieldList = adminFieldService.queryUpdateField(CrmEnum.PSI_STOREHOUSE.getType(), storehouse);
        fieldList.add(new Record().set("fieldName", "map_address")
                .set("name", "地区定位")
                .set("value", Kv.by("location", storehouse.getStr("location"))
                        .set("address", storehouse.getStr("address"))
                        .set("detailAddress", storehouse.getStr("detail_address"))
                        .set("lng", storehouse.getStr("lng"))
                        .set("lat", storehouse.getStr("lat")))
                .set("formType", "map_address")
                .set("isNull", 0));
        return fieldList;
    }

    /**
     * @author wyq
     * 根据id删除仓库
     */
    public R deleteByIds(String storehouseIds){
        String[] idsArr = storehouseIds.split(",");
        List<Record> idsList = new ArrayList<>();
        for(String id : idsArr){
            if(!BaseUtil.getUserId().equals(BaseConstant.SUPER_ADMIN_USER_ID) && !BaseUtil.getUser().getRoles().contains(BaseConstant.SUPER_ADMIN_ROLE_ID)){
                // TODO 测试时需要确认表是否加ro_user_id和rw_user_id && Db.queryInt(Db.getSql("crm.customer.queryIsRoUser"), BaseUtil.getUserId(), id) > 0
                return R.error("没有权限");
            }
            Record record = new Record();
            idsList.add(record.set("storehouse_id", Integer.valueOf(id)));
        }
        Integer stockpileQuantity = Db.queryInt(Db.getSql("psi.storehouse.queryStockpileQuantity"), storehouseIds);
        if(stockpileQuantity > 0){
            return R.error("该仓库中存在商品，请勿删除。如需删除请将商品出库后再删除该仓库。");
        }
        List<Record> batchIdList = Db.find(Db.getSqlPara("psi.storehouse.queryBatchIdByIds", Kv.by("ids", idsArr)));
        return Db.tx(() -> {
            Db.batch(Db.getSql("psi.storehouse.deleteByIds"), "storehouse_id", idsList, 100);
//            Db.batch("delete from yzcrm_admin_fieldv where batch_id = ?", "batch_id", batchIdList, 100);
            return true;
        }) ? R.ok() : R.error();
    }

    /**
     * @author wyq
     * 基本信息
     */
    public List<Record> information(Integer customerId) {
        Record record = queryById(customerId);
        List<String> keyList = Arrays.asList("name", "仓库编号", "备注", "状态");
        List<Record> recordList = adminFieldService.queryInformation(CrmEnum.PSI_STOREHOUSE, record, keyList);
        recordList.add(new Record().set("name","地区定位").set("value",Kv.by("location", record.getStr("location"))
                .set("address", record.getStr("address"))
                .set("detailAddress", record.getStr("detail_address"))
                .set("lng", record.getStr("lng"))
                .set("lat", record.getStr("lat"))).set("formType","map_address").set("field_type",1));
        return recordList.stream().sorted(Comparator.comparingInt(r->-r.getInt("field_type"))).map(r-> r.remove("field_type","field_name","setting","type")).collect(Collectors.toList());
    }



    /**
     * 查询进销存在库商品
     * @param productId
     * @param productName
     * @param productStatus
     * @param productNameEn
     * @param productNum
     * @param productSpecName
     * @param storehouseId
     * @param storehouseCode
     * @param storehouseName
     * @param productBatchId
     * @param productUpcCode
     * @return
     */
    public R queryStorehouse(Integer productId,
                                       String productName,
                                       Integer productStatus,
                                       String productNameEn,
                                       String productNum,
                                       String productSpecName,
                                       Integer storehouseId,
                                       String storehouseCode,
                                       String storehouseName,
                                       String productBatchId,
                                       String productUpcCode,
                                       String elsNum,
                                       int page,
                                       int limit){

        Kv kv = Kv.by("productName", productName).set("productId", productId).set("productStatus", productStatus)
                .set("productNameEn", productNameEn).set("productNum", productNum).set("productSpecName", productSpecName)
                .set("storehouseId", storehouseId).set("storehouseCode", storehouseCode).set("storehouseName", storehouseName)
                .set("productBatchId", productBatchId).set("productUpcCode", productUpcCode)
                .set("elsNum", elsNum);


        Long userId = BaseUtil.getUserId();
        JSONObject jsonObject= Aop.get(AdminRoleService.class).auth(userId);
        List<String> authList= AuthUtil.queryAuth(jsonObject, "");

        String priceType;
        if (authList.contains("psi:querystorehouse:querystorehouse_purchaser")){

            priceType = "purchaser";
        } else if (authList.contains("psi:querystorehouse:querystorehouse_director")){

            priceType = "director";
        } else if (authList.contains("psi:querystorehouse:querystorehouse_salesman")){

            priceType = "salesman";
        } else  {

            priceType = "";
        }

        // 获取入库
        List<Record> records = Db.find(Db.getSqlPara("psi.stockpile.queryStockpile",
                kv.set("page", (page - 1) * limit).set("limit", limit).set("priceType", priceType)));

        SqlPara countSql = Db.getSqlPara("psi.stockpile.queryStockpileCount", kv);
        Integer count = Db.queryInt(countSql.getSql(), countSql.getPara());

//        Integer count = Db.queryInt(Db.getSql("psi.stockpile.queryStockpileCount"),
//                productId,productName,productStatus,productNameEn,productNum
//                , productSpecName,storehouseId,storehouseCode,storehouseName);

        JSONObject resultJsonObject = new JSONObject();
        resultJsonObject.put("list", records);
        resultJsonObject.put("totalRow", count);
        return R.ok().put("data", resultJsonObject);
    }

    /**
     * 检索在库表头信息
     * @return
     */
    public List<Record> queryStorehouseListHead() {

        List<Record> listHead = new ArrayList<>();
//        listHead.add(new Record().set("name","仓库ID").set("fieldName","storehouseId"));
        listHead.add(new Record().set("name","仓库名称").set("fieldName","storehouseName"));
//        listHead.add(new Record().set("name","产品ID").set("fieldName","productId"));
        listHead.add(new Record().set("name","产品编号").set("fieldName","num"));
        listHead.add(new Record().set("name","产品名称").set("fieldName","productName"));
        listHead.add(new Record().set("name","产品英文名称").set("fieldName","productNameEn"));
        listHead.add(new Record().set("name","在库数量").set("fieldName","quantity"));
        listHead.add(new Record().set("name","单位").set("fieldName","unit"));
        listHead.add(new Record().set("name","使用范围").set("fieldName","productType")); // 名称
        listHead.add(new Record().set("name","中文描述").set("fieldName","description"));
        listHead.add(new Record().set("name","产品规格").set("fieldName","specName"));

        Long userId = BaseUtil.getUserId();
        JSONObject jsonObject= Aop.get(AdminRoleService.class).auth(userId);
        List<String> authList= AuthUtil.queryAuth(jsonObject, "");

        if (authList.contains("psi:querystorehouse:querystorehouse_purchaser")){

            listHead.add(new Record().set("name","成本单价（未税）").set("fieldName","costPriceNoTax"));
            listHead.add(new Record().set("name","成本单价（含税）").set("fieldName","costPriceTax"));
            listHead.add(new Record().set("name","结算单价 （未税）").set("fieldName","settlementPriceNoTax"));
            listHead.add(new Record().set("name","结算单价（含税）").set("fieldName","settlementPriceTax"));
            listHead.add(new Record().set("name","总监权限单价（含税）").set("fieldName","directorPriceTax"));
            listHead.add(new Record().set("name","销售表价（含税）").set("fieldName","salesPriceTax"));

        } else if (authList.contains("psi:querystorehouse:querystorehouse_director")){

            listHead.add(new Record().set("name","结算单价 （未税）").set("fieldName","settlementPriceNoTax"));
            listHead.add(new Record().set("name","结算单价（含税）").set("fieldName","settlementPriceTax"));
            listHead.add(new Record().set("name","总监权限单价（含税）").set("fieldName","directorPriceTax"));
            listHead.add(new Record().set("name","销售表价（含税）").set("fieldName","salesPriceTax"));

        }else if (authList.contains("psi:querystorehouse:querystorehouse_salesman")){

            listHead.add(new Record().set("name","销售表价（含税）").set("fieldName","salesPriceTax"));

        } else {

        }
//        listHead.add(new Record().set("name","").set("fieldName","stockpile_id"));
//        listHead.add(new Record().set("name","批次号").set("fieldName","batch_id"));
//        listHead.add(new Record().set("name","序列号").set("fieldName","upc_code"));
//        listHead.add(new Record().set("name","名称").set("fieldName","label")); // 模块名称
//        listHead.add(new Record().set("name","出入库编号").set("fieldName","link_id"));

        return listHead;
    }
}
